<?php
class MY_Model extends CI_Model {
	var $id = null;
	var $created_on = '';
	var $updated_on = '';
	var $valid = 1;
	var $created_by = '';
	var $updated_by = '';

    function __construct()
    {
        parent::__construct();
    }
    
    
    function insert()
    {
    	$this->_setBaseValues(TRUE);
        return $this->db->insert($this->table(), $this);
    }

    function update()
    {
    	$this->_setBaseValues(FALSE);
        return $this->db->update($this->table(), $this, array('id' => $this->id));
    }
	
	
	private function _setBaseValues($isInsert){
		
		$currentuser = "";
		
		$this->valid = 1;
		
		if($this->session->userdata('user_id') != null){
			$currentuser = $this->session->userdata('user_id');
		}
	    if($this->session->userdata('client_id') != null){
			$currentuser = $this->session->userdata('client_id');
		}
		
		
		if($isInsert){
			$this->created_on = date('Y-m-d H:i:s');
			
			$this->created_by = $currentuser;
			
		}else if(isset($this->id)){
			$record = $this->getEntryById($this->id);
    		$this->created_by = $record[0]->created_by;
    		$this->created_on = $record[0]->created_on;
		}
			
		$this->updated_on = date('Y-m-d H:i:s'); 
		
		$this->updated_by =$currentuser;
	}
	
	
    function getAllEntries(){
    	 $this->db->where('valid', 1);
	     $query = $this->db->get($this->table());
	     return $query->result();	
    
    }
    
    function getAllEntriesWithJoin($join_tables = array(),$limit = 0, $start = 0) {
    	 $table = $this->table();
    	 
    	 $this->db->select($this->buildSelectFields($this));
		 
		 if(count($join_tables) != 0) {
		 	//$this->db->join('comments', 'comments.id = table.id');
		 	foreach($join_tables as $key => $val) {
		 		
		 		$this->db->select($this->buildSelectFields($val));
		 		
		 		$join_table = strtolower(str_replace("_model", "", get_class($val)));
		 		
		 		$this->db->join($join_table, $this->_matchTableToField($join_table, $this->getForeignKeys($this)));
		 		
		 	}
		 }
		 
		 $this->db->where("$table.valid", 1);
		 
		 if($limit > 0 & $start > 0)
		 	$this->db->limit($limit,$start);
		 else if ($limit > 0)
		 	$this->db->limit($limit);
		 
	     $query = $this->db->get($this->table());
	     
	     return $query->result_object();
    }
    
    /**
     * 
     * Transform all the field names of the table from {table.field_name} to {table_field_name}
     * 
     * @param Object $table
     * @return String $select
     */
    private function buildSelectFields($table) {
    	
    	$select = "";
    
    	$variables = $this->getVariables($table);
    	
    	$ctr = 1;
    	
    	foreach($variables as $key => $val) {
    		$select .= $this->_getTableName($table) . "." . $key . " AS " . $this->_getTableName($table) . "_" . $key;
    		
    		if($ctr < count($variables))
    			$select .= ",";
    			
    		$ctr++;
    	}
    	
    	return $select;
    }
    
    /**
     * 
     * Create join statement
     *  
     * @param String $tablename
     * @param Array $foreign_keys
     */
    private function _matchTableToField($tablename, $foreign_keys = array()) {
    	
    	if(count($foreign_keys) > 1) {
    		
	    	foreach($foreign_keys as $key => $val) {

	    		if($tablename === str_replace("_id", "",$val))
	    			return "$tablename.id = " . $this->table() . "." . $val;
	    			
	    	}
    	}
		    	
    	return "$tablename.id = " . $this->table() . "." . $foreign_keys[0];
    }
    
    function getEntryById($id){
 	  	$entry = $this->db->query("select * from ".$this->table()." where id = $id and valid = 1 limit 1"); 
 	  	return $entry->result();
    }
    
    function getEntryByName($name){
 	  	$entry = $this->db->query("select * from ".$this->table()." where name = '$name' and valid = 1 limit 1"); 
 	  	return $entry->result();
    }
	
    function delete($id){
    	return $this->db->query("update ".$this->table()." set valid = 0 where id = $id and valid = 1 limit 1"); 
    }
    

    public function record_count() {
        return $this->db->count_all($this->table());
    }

    public function limit($limit, $start) {
    	$this->db->where('valid',1);
        $this->db->limit($limit, $start);
        $query = $this->db->get($this->table());
        return $query->result();
   }
   
  public function limitAndLike($limit, $start ,$field ,  $keyword) {
  		$this->db->like($field,$keyword);
        $this->db->limit($limit, $start);
        $query = $this->db->get($this->table());
        return $query->result();
   }
    
    function table(){
	    /*********************************************
	     * $this->table() is the tablename
	     * $this->setBaseValues($isInsert)--CreatedOn,UpdatedOn,createdBy,CreatedOn,valid
	     * *******************************************
	     */
    	
    	//model class name == current called class == needed table
    	
    	
    	if(preg_match('/_model$/', get_called_class())==1) {
    		$tablename = str_replace("_model", "", get_called_class());
    	} else {
    		show_error("Naming convention model class must be 'tablename_model'",500,"Error Model Name");
    	}
    	
    	return strtolower($tablename);
    }
    
    private function _getTableName($table) {
    	return strtolower(str_replace("_model", "", get_class($table)));
    }
    
    /**
     * 
     * Get all instance variables of object
     * 
     * @param Object $obj
     */
    protected function getVariables($obj) {
    	return get_object_vars($obj);
    }
    
    
    /**
     * 
     * Get all instance variables that ends with _id
     * assuming all variables that ends with _id are foreign keys
     * and has the same name with table fields
     * 
     * @param Object $obj 
     * 
     * @return Array of foreign keys
     */
    protected function getForeignKeys($obj) {
    	
    	$foreign_keys = array();
    	
    	foreach($this->getVariables($obj) as $key => $val) {
		 	if(preg_match('/_id$/', $key)==1) 
		 		array_push($foreign_keys, $key);
		}
		
		return $foreign_keys;
    }
    
    public function __toString() {
    	return $this->id;
    }
}